package com.zjl.search.service;

import com.alibaba.fastjson.JSON;
import com.zjk.pojo.product.SearchItem;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.index.query.*;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author: gfk
 * @create: 2022/11/4
 * @Description:
 * @FileName: SearchService
 * @History:
 * @自定义内容：
 */
@Service
public class SearchService {

    @Value("${exam5.elasticsearch.index}")
    private String index;

    @Autowired
    RestHighLevelClient restHighLevelClient;

    public Map search(Integer pageNo, Integer pageSize, Map searchMap) throws IOException {

        String keyword = (String) searchMap.get("keyword");
        String min = (String) searchMap.get("min");
        String max = (String) searchMap.get("max");
        String status = (String) searchMap.get("status");


        SearchRequest searchRequest = new SearchRequest(index);
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();//{

        //分页
        Integer pageNum=(pageNo-1)*pageSize;
        sourceBuilder.from(pageNum);
        sourceBuilder.size(pageSize);

        //模糊查询
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();//query下的bool4
        if (!StringUtils.isEmpty(keyword)){
            MultiMatchQueryBuilder matchQuery = QueryBuilders.multiMatchQuery(keyword,"name","period");
            boolQueryBuilder.must(matchQuery); //query - bool - must
        }


        //区间查询
        if (!StringUtils.isEmpty(min) || !StringUtils.isEmpty(max)) {
            RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("maxMoney");
            if (!StringUtils.isEmpty(min)) {
                rangeQueryBuilder.gte(min);
            }
            if (!StringUtils.isEmpty(max)){
                rangeQueryBuilder.lte(max);
            }

            boolQueryBuilder.filter(rangeQueryBuilder); //query - bool -filter
        }

            //根据 状态查询
        if (!StringUtils.isEmpty(status)){
            TermQueryBuilder status1 = QueryBuilders.termQuery("status", status);
            boolQueryBuilder.filter(status1);
        }
        //查询
        sourceBuilder.query(boolQueryBuilder);

        //根据最大金额 排序
        sourceBuilder.sort("maxMoney", SortOrder.DESC);

        //高亮查询
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.preTags("<strong style ='color:red'>");
        highlightBuilder.postTags("</strong>");
        highlightBuilder.field("name");
        sourceBuilder.highlighter(highlightBuilder);


        searchRequest.source(sourceBuilder);//}

        SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);//点击发送

        //高亮
        SearchHits hits = search.getHits();
        long total = hits.getTotalHits().value;
         SearchHit[] hits1 = hits.getHits();
        List<SearchItem> searchItems= new ArrayList<>();
        for (SearchHit documentFields : hits1) {
            //高亮结果的处理
             String asString = documentFields.getSourceAsString();
             SearchItem searchItem = JSON.parseObject(asString, SearchItem.class);
             Map<String, HighlightField> map = documentFields.getHighlightFields();

             HighlightField name = map.get("name");
             if (name!=null){
                 Text[] fragments = name.getFragments();
                 if (fragments.length>0){
                     String hisg= fragments[0].string();
                     searchItem.setName(hisg);
                 }
             }
            searchItems.add(searchItem);
        }


        Map hashMap = new HashMap<>();
        hashMap.put("total",total);
        hashMap.put("searchItemList",searchItems);

        return hashMap;
    }
}
